#ifndef __VIDEO_MP4_CLIENT_STREAM_H__
#define __VIDEO_MP4_CLIENT_STREAM_H__

#include <map>
#include <mutex>
#include <string>
#include <functional>
#include "Pal/VideoDec.h"
#include "json.h"
#include "Thread/Thread.h"
#include "StreamComposeMgr.h"
#include "AudioDecode.h"
#include "Poller/Timer.h"
#include "frame_common.h"
#include <queue>



#define H264_NALU_SEI  6
#define H264_NALU_AUD  9


namespace Media {

class VideoDecode;


typedef enum
{
    MP4_ONLINE_STREAMER = 0,
    MP4_LOCAL_STREAMER,
    MP4_ONLINE_BGM,
    MP4_LOCAL_BGM
    
}Mp4StreamType;
    
class Mp4ClientStream {
  
private:
	const uint16_t QueueSize = 100;
	//视频数据集
	struct FrameBuffer
	{
		uint64_t timestamp; /*< timestamp*/
		size_t size; /*< data length*/
		uint8_t* data; /*< raw data*/

		FrameBuffer(size_t len)
			: timestamp(0)
			, size(len)
			, data(NULL)
		{
			data = new uint8_t[len];
		}

		~FrameBuffer()
		{
			delete[]data;
			data = NULL;
		}

		FrameBuffer(const FrameBuffer&);
		FrameBuffer& operator=(const FrameBuffer&);
	};

	// 定义智能指针
	typedef std::shared_ptr<FrameBuffer> FramePtr;

public:

	static Mp4ClientStream* instance(Mp4StreamType type);

	bool stop();

	bool start(StreamPlayInfo playInfo);

	bool onFrame(const FrameCommon::Frame::Ptr& frame);

	bool onStop();

	void getAudioInfo(const FrameCommon::AudioFormat& frame);

	bool setVpnAddr(std::string& vpnAddr);

	void getVideoInfo(const FrameCommon::VideoFormat& frame);

	bool setRepetInfo(bool repet);

private:
	Mp4ClientStream(Mp4StreamType type);

	bool streamStart();

	bool streamStop(void);

	bool sendVideoPacket(unsigned char* buffer, int buflen, uint64_t timestamp);

	bool sendAudioPacket(unsigned char* buffer, int buflen);

	bool SaveToCommQueue(FramePtr& msg);

	bool GetCommQueueMsg(FramePtr& msg);

	void StreamInProc(Fdt::Thread* thread);

	bool clearVideoQueue();

	bool setAudioDecode(int channel, int frequency, int depth);

	bool setVideoDecode(VideoEncType type);

private:
	static std::map<Mp4StreamType, Mp4ClientStream*>  sm_streamMap;

	static std::recursive_mutex 			sm_mapMutex;

	VideoDecode*                            m_pVideoDecode = nullptr;

	int 									m_videoChannel = -1;

	bool									m_started = false; //start作为启动标志,避免多个业务多次启停

	bool									m_started_audio = false;

	VideoDecPacket                          m_videoPacket;

	std::string								m_vpnAddr;

	FrameCommon::Mp4Player::Ptr         	m_mp4Client = nullptr;

	std::string                             m_mp4Conent;

	std::shared_ptr<Fdt::Timer>             m_taskTimer;

	TaskInfo                                m_taskInfo = { 0 };

	StreamAbility                           m_playAbility = VIDEO_AUDIO;

	AudioDecode*                            m_pAudioDecode = nullptr;

	AudioDecPacket                          m_audioPacket;

	int 									m_audioChannel = -1;

	bool                                    m_dropFrame = true;

	Mp4StreamType                           m_streamType = MP4_ONLINE_STREAMER;

	std::mutex                              m_queueMutex;

	std::queue<FramePtr>                    m_frameaQueue;

	FramePtr                                m_framePtr;

	VideoEncType                            m_videoEncType;

	bool                                    m_mp4RepetInfo = false;

	Fdt::Thread 						    m_streamInThread{ "Mp4ClientStream" };//thread放在最后,保证thread最后构造,最先析构

	Fdt::Thread 						    m_thread{ "Mp4ClientStream" };//thread放在最后,保证thread最后构造,最先析构

};

}

#endif  // __VIDEO_MP4_CLIENT_STREAM_H__